package com.datagateway.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 数据源配置类
 * 支持多种数据源的配置管理
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@Configuration
@ConfigurationProperties(prefix = "datagateway.datasource")
public class DataSourceConfig {

    /**
     * 是否启用多数据源支持
     */
    private boolean enabled = true;

    /**
     * 默认数据源名称
     */
    private String defaultDataSource = "hive";

    /**
     * 最大连接数
     */
    private int maxConnections = 100;

    /**
     * 连接超时时间（毫秒）
     */
    private long connectionTimeout = 30000;

    /**
     * 查询超时时间（毫秒）
     */
    private long queryTimeout = 60000;

    /**
     * 批量大小
     */
    private int batchSize = 1000;

    /**
     * 是否自动提交
     */
    private boolean autoCommit = true;

    /**
     * 是否启用连接池
     */
    private boolean poolingEnabled = true;

    /**
     * 连接池大小
     */
    private int poolSize = 10;

    /**
     * 连接池超时时间（毫秒）
     */
    private long poolTimeout = 30000;

    /**
     * MySQL数据源配置
     */
    private Map<String, MySQLConfig> mysql = new HashMap<>();

    /**
     * PostgreSQL数据源配置
     */
    private Map<String, PostgreSQLConfig> postgresql = new HashMap<>();

    /**
     * MongoDB数据源配置
     */
    private Map<String, MongoDBConfig> mongodb = new HashMap<>();

    /**
     * Redis数据源配置
     */
    private Map<String, RedisConfig> redis = new HashMap<>();

    /**
     * Elasticsearch数据源配置
     */
    private Map<String, ElasticsearchConfig> elasticsearch = new HashMap<>();

    /**
     * Hive数据源配置
     */
    private Map<String, HiveConfig> hive = new HashMap<>();

    // Getters and Setters
    public boolean isEnabled() { return enabled; }
    public void setEnabled(boolean enabled) { this.enabled = enabled; }
    public String getDefaultDataSource() { return defaultDataSource; }
    public void setDefaultDataSource(String defaultDataSource) { this.defaultDataSource = defaultDataSource; }
    public int getMaxConnections() { return maxConnections; }
    public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
    public long getConnectionTimeout() { return connectionTimeout; }
    public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; }
    public long getQueryTimeout() { return queryTimeout; }
    public void setQueryTimeout(long queryTimeout) { this.queryTimeout = queryTimeout; }
    public int getBatchSize() { return batchSize; }
    public void setBatchSize(int batchSize) { this.batchSize = batchSize; }
    public boolean isAutoCommit() { return autoCommit; }
    public void setAutoCommit(boolean autoCommit) { this.autoCommit = autoCommit; }
    public boolean isPoolingEnabled() { return poolingEnabled; }
    public void setPoolingEnabled(boolean poolingEnabled) { this.poolingEnabled = poolingEnabled; }
    public int getPoolSize() { return poolSize; }
    public void setPoolSize(int poolSize) { this.poolSize = poolSize; }
    public long getPoolTimeout() { return poolTimeout; }
    public void setPoolTimeout(long poolTimeout) { this.poolTimeout = poolTimeout; }
    public Map<String, MySQLConfig> getMysql() { return mysql; }
    public void setMysql(Map<String, MySQLConfig> mysql) { this.mysql = mysql; }
    public Map<String, PostgreSQLConfig> getPostgresql() { return postgresql; }
    public void setPostgresql(Map<String, PostgreSQLConfig> postgresql) { this.postgresql = postgresql; }
    public Map<String, MongoDBConfig> getMongodb() { return mongodb; }
    public void setMongodb(Map<String, MongoDBConfig> mongodb) { this.mongodb = mongodb; }
    public Map<String, RedisConfig> getRedis() { return redis; }
    public void setRedis(Map<String, RedisConfig> redis) { this.redis = redis; }
    public Map<String, ElasticsearchConfig> getElasticsearch() { return elasticsearch; }
    public void setElasticsearch(Map<String, ElasticsearchConfig> elasticsearch) { this.elasticsearch = elasticsearch; }
    public Map<String, HiveConfig> getHive() { return hive; }
    public void setHive(Map<String, HiveConfig> hive) { this.hive = hive; }

    /**
     * MySQL配置
     */
    public static class MySQLConfig {
        private String url;
        private String username;
        private String password;
        private String driver = "com.mysql.cj.jdbc.Driver";
        private String table = "processed_data";
        private int maxConnections = 20;
        private long connectionTimeout = 30000;
        private boolean useSSL = false;
        private String serverTimezone = "UTC";
        private boolean autoReconnect = true;
        private String characterEncoding = "UTF-8";

        // Getters and Setters
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getDriver() { return driver; }
        public void setDriver(String driver) { this.driver = driver; }
        public String getTable() { return table; }
        public void setTable(String table) { this.table = table; }
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
        public long getConnectionTimeout() { return connectionTimeout; }
        public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; }
        public boolean isUseSSL() { return useSSL; }
        public void setUseSSL(boolean useSSL) { this.useSSL = useSSL; }
        public String getServerTimezone() { return serverTimezone; }
        public void setServerTimezone(String serverTimezone) { this.serverTimezone = serverTimezone; }
        public boolean isAutoReconnect() { return autoReconnect; }
        public void setAutoReconnect(boolean autoReconnect) { this.autoReconnect = autoReconnect; }
        public String getCharacterEncoding() { return characterEncoding; }
        public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; }
    }

    /**
     * PostgreSQL配置
     */
    public static class PostgreSQLConfig {
        private String url;
        private String username;
        private String password;
        private String driver = "org.postgresql.Driver";
        private String table = "processed_data";
        private int maxConnections = 20;
        private long connectionTimeout = 30000;
        private boolean ssl = false;
        private String sslMode = "disable";
        private String characterEncoding = "UTF-8";
        private String stringType = "unspecified";

        // Getters and Setters
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getDriver() { return driver; }
        public void setDriver(String driver) { this.driver = driver; }
        public String getTable() { return table; }
        public void setTable(String table) { this.table = table; }
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
        public long getConnectionTimeout() { return connectionTimeout; }
        public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; }
        public boolean isSsl() { return ssl; }
        public void setSsl(boolean ssl) { this.ssl = ssl; }
        public String getSslMode() { return sslMode; }
        public void setSslMode(String sslMode) { this.sslMode = sslMode; }
        public String getCharacterEncoding() { return characterEncoding; }
        public void setCharacterEncoding(String characterEncoding) { this.characterEncoding = characterEncoding; }
        public String getStringType() { return stringType; }
        public void setStringType(String stringType) { this.stringType = stringType; }
    }

    /**
     * MongoDB配置
     */
    public static class MongoDBConfig {
        private String connectionString;
        private String database = "datagateway";
        private String collection = "processed_data";
        private int maxConnections = 20;
        private long connectionTimeout = 30000;
        private int maxWaitTime = 120000;
        private int maxIdleTime = 0;
        private int maxLifeTime = 0;
        private int minConnections = 0;
        private int maxConnectionIdleTime = 0;
        private int maxConnectionLifeTime = 0;

        // Getters and Setters
        public String getConnectionString() { return connectionString; }
        public void setConnectionString(String connectionString) { this.connectionString = connectionString; }
        public String getDatabase() { return database; }
        public void setDatabase(String database) { this.database = database; }
        public String getCollection() { return collection; }
        public void setCollection(String collection) { this.collection = collection; }
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
        public long getConnectionTimeout() { return connectionTimeout; }
        public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; }
        public int getMaxWaitTime() { return maxWaitTime; }
        public void setMaxWaitTime(int maxWaitTime) { this.maxWaitTime = maxWaitTime; }
        public int getMaxIdleTime() { return maxIdleTime; }
        public void setMaxIdleTime(int maxIdleTime) { this.maxIdleTime = maxIdleTime; }
        public int getMaxLifeTime() { return maxLifeTime; }
        public void setMaxLifeTime(int maxLifeTime) { this.maxLifeTime = maxLifeTime; }
        public int getMinConnections() { return minConnections; }
        public void setMinConnections(int minConnections) { this.minConnections = minConnections; }
        public int getMaxConnectionIdleTime() { return maxConnectionIdleTime; }
        public void setMaxConnectionIdleTime(int maxConnectionIdleTime) { this.maxConnectionIdleTime = maxConnectionIdleTime; }
        public int getMaxConnectionLifeTime() { return maxConnectionLifeTime; }
        public void setMaxConnectionLifeTime(int maxConnectionLifeTime) { this.maxConnectionLifeTime = maxConnectionLifeTime; }
    }

    /**
     * Redis配置
     */
    public static class RedisConfig {
        private String host = "localhost";
        private int port = 6379;
        private String password;
        private int database = 0;
        private int timeout = 2000;
        private String keyPrefix = "datagateway:";
        private String dataType = "hash";
        private int expireSeconds = 3600;
        private int maxTotal = 100;
        private int maxIdle = 20;
        private int minIdle = 5;
        private boolean testOnBorrow = true;
        private boolean testOnReturn = true;
        private boolean testWhileIdle = true;

        // Getters and Setters
        public String getHost() { return host; }
        public void setHost(String host) { this.host = host; }
        public int getPort() { return port; }
        public void setPort(int port) { this.port = port; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public int getDatabase() { return database; }
        public void setDatabase(int database) { this.database = database; }
        public int getTimeout() { return timeout; }
        public void setTimeout(int timeout) { this.timeout = timeout; }
        public String getKeyPrefix() { return keyPrefix; }
        public void setKeyPrefix(String keyPrefix) { this.keyPrefix = keyPrefix; }
        public String getDataType() { return dataType; }
        public void setDataType(String dataType) { this.dataType = dataType; }
        public int getExpireSeconds() { return expireSeconds; }
        public void setExpireSeconds(int expireSeconds) { this.expireSeconds = expireSeconds; }
        public int getMaxTotal() { return maxTotal; }
        public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; }
        public int getMaxIdle() { return maxIdle; }
        public void setMaxIdle(int maxIdle) { this.maxIdle = maxIdle; }
        public int getMinIdle() { return minIdle; }
        public void setMinIdle(int minIdle) { this.minIdle = minIdle; }
        public boolean isTestOnBorrow() { return testOnBorrow; }
        public void setTestOnBorrow(boolean testOnBorrow) { this.testOnBorrow = testOnBorrow; }
        public boolean isTestOnReturn() { return testOnReturn; }
        public void setTestOnReturn(boolean testOnReturn) { this.testOnReturn = testOnReturn; }
        public boolean isTestWhileIdle() { return testWhileIdle; }
        public void setTestWhileIdle(boolean testWhileIdle) { this.testWhileIdle = testWhileIdle; }
    }

    /**
     * Elasticsearch配置
     */
    public static class ElasticsearchConfig {
        private String host = "localhost";
        private int port = 9200;
        private String scheme = "http";
        private String username;
        private String password;
        private String index = "datagateway";
        private int searchSize = 100;
        private int maxConnections = 20;
        private long connectionTimeout = 30000;
        private int maxRetries = 3;
        private long retryDelay = 1000;

        // Getters and Setters
        public String getHost() { return host; }
        public void setHost(String host) { this.host = host; }
        public int getPort() { return port; }
        public void setPort(int port) { this.port = port; }
        public String getScheme() { return scheme; }
        public void setScheme(String scheme) { this.scheme = scheme; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getIndex() { return index; }
        public void setIndex(String index) { this.index = index; }
        public int getSearchSize() { return searchSize; }
        public void setSearchSize(int searchSize) { this.searchSize = searchSize; }
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
        public long getConnectionTimeout() { return connectionTimeout; }
        public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; }
        public int getMaxRetries() { return maxRetries; }
        public void setMaxRetries(int maxRetries) { this.maxRetries = maxRetries; }
        public long getRetryDelay() { return retryDelay; }
        public void setRetryDelay(long retryDelay) { this.retryDelay = retryDelay; }
    }

    /**
     * Hive配置
     */
    public static class HiveConfig {
        private String url;
        private String username;
        private String password;
        private String driver = "org.apache.hive.jdbc.HiveDriver";
        private String table = "processed_data";
        private int maxConnections = 20;
        private long connectionTimeout = 30000;
        private String transportMode = "binary";
        private String saslQop = "auth";
        private boolean useSSL = false;

        // Getters and Setters
        public String getUrl() { return url; }
        public void setUrl(String url) { this.url = url; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getPassword() { return password; }
        public void setPassword(String password) { this.password = password; }
        public String getDriver() { return driver; }
        public void setDriver(String driver) { this.driver = driver; }
        public String getTable() { return table; }
        public void setTable(String table) { this.table = table; }
        public int getMaxConnections() { return maxConnections; }
        public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
        public long getConnectionTimeout() { return connectionTimeout; }
        public void setConnectionTimeout(long connectionTimeout) { this.connectionTimeout = connectionTimeout; }
        public String getTransportMode() { return transportMode; }
        public void setTransportMode(String transportMode) { this.transportMode = transportMode; }
        public String getSaslQop() { return saslQop; }
        public void setSaslQop(String saslQop) { this.saslQop = saslQop; }
        public boolean isUseSSL() { return useSSL; }
        public void setUseSSL(boolean useSSL) { this.useSSL = useSSL; }
    }
}
